package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.zzyl.base.PageBean;
import com.zzyl.constant.SuperConstant;
import com.zzyl.dto.UserDto;
import com.zzyl.entity.Role;
import com.zzyl.entity.User;
import com.zzyl.entity.UserRole;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.*;
import com.zzyl.properties.SecurityProperties;
import com.zzyl.service.UserService;
import com.zzyl.utils.NoProcessing;
import com.zzyl.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 用户表服务实现类
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserMapper userMapper;
    @Autowired
    UserRoleMapper userRoleMapper;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    DeptMapper deptMapper;
    @Autowired
    PostMapper postMapper;
    @Autowired
    SecurityProperties securityProperties;

    /**
     * 用户分页
     *
     * @param userDto
     * @param pageNum
     * @param pageSize
     */
    @Override
    public PageBean<UserVo> selectPage(UserDto userDto, Integer pageNum, Integer pageSize) {
        if (ObjectUtil.isNotEmpty(userDto.getDeptNo())) {
            //处理部门编号，提取有效位前缀   100200300000 -> 100200300
            userDto.setDeptNo(NoProcessing.processString(userDto.getDeptNo()));
        }

        //开启分页
        PageHelper.startPage(pageNum, pageSize);

        //调用业务层查询数据
        Page<User> page = userMapper.selectPage(userDto); //只查询用户、部门、职位数据，角色数据在业务层补全（因为用户和角色是一对多关系）

        PageBean<UserVo> pageBean = PageBean.of(page, UserVo.class);

        if (CollUtil.isEmpty(pageBean.getRecords())) {
            return pageBean;
        }

        //处理每个用户对应的角色
        pageBean.getRecords().forEach(userVo -> {
            //查询对应角色
            List<Role> roleList = roleMapper.findRoleListByUserId(userVo.getId());

            //提取集合中每个Role对象的id属性
            List<String> roleVoIds = CollUtil.getFieldValues(roleList, "id", String.class);
            //提取集合中每个Role对象的roleName属性
            List<String> roleLabels = CollUtil.getFieldValues(roleList, "roleName", String.class);

            //设置角色的ids
            userVo.setRoleVoIds(Set.copyOf(roleVoIds));
            //设置角色名称
            userVo.setRoleLabels(Set.copyOf(roleLabels));
        });

        //返回数据
        return pageBean;
    }

    /**
     * 用户添加
     *
     * @param userDto
     */
    @Override
    public void addUser(UserDto userDto) {
       //根据部门编号查询，是否是最底层的部门，如果不是，不允许添加用户
        int count = deptMapper.isLowestDept(userDto.getDeptNo());
        if (count > 0) {
            throw new BaseException(BasicEnum.USER_LOCATED_BOTTOMED_DEPT);
        }

        //转换UserVo为User
        User user = BeanUtil.toBean(userDto, User.class);
        user.setUsername(user.getEmail());
        user.setNickName(user.getRealName());
        user.setDataState(SuperConstant.DATA_STATE_0);
        String password = BCrypt.hashpw(securityProperties.getDefaultPassword(), BCrypt.gensalt());
        user.setPassword(password);

        userMapper.insert(user);

        //保存用户角色中间表
        List<UserRole> userRoles = Lists.newArrayList();
        userDto.getRoleVoIds().forEach(r -> {
            userRoles.add(UserRole.builder()
                    .userId(user.getId())
                    .roleId(Long.valueOf(r))
                    .dataState(SuperConstant.DATA_STATE_0)
                    .build());
        });
        userRoleMapper.batchInsert(userRoles);
    }

    /**
     * 删除用户
     *
     *
     *
     */
    @Override
    public void deleteUserById(Long userId) {
        // 删除用户与角色关联
        userRoleMapper.deleteUserRoleByUserId(userId);
        // 删除用户与岗位关联
        userMapper.deleteByPrimaryKey(userId);
    }

    /**
     * 启用禁用
     *
     * @param id
     * @param status
     */
    @Override
    public void isEnable(Long id, Integer status) {
        User user = User.builder().id(id).dataState(status.toString()).build();
        userMapper.updateByPrimaryKeySelective(user);
    }

    /**
     * 用户列表
     */
    @Override
    public List<UserVo> list() {
        List<User> users = userMapper.selectList();
        return BeanUtil.copyToList(users, UserVo.class);
    }

    /**
     * 用户修改
     *
     * @param userDto
     */
    @Override
    public void updateUser(UserDto userDto) {
        //根据部门编号查询，是否是最底层的部门，如果不是，不允许添加用户
        int count = deptMapper.isLowestDept(userDto.getDeptNo());
        if (count > 0) {
            throw new BaseException(BasicEnum.USER_LOCATED_BOTTOMED_DEPT);
        }

        //转换UserVo为User
        User user = BeanUtil.toBean(userDto, User.class);
        user.setUsername(userDto.getEmail());
        userMapper.updateByPrimaryKeySelective(user);

        if (CollUtil.isEmpty(userDto.getRoleVoIds())) {
            return;
        }

        //删除角色中间表
        userRoleMapper.deleteUserRoleByUserId(user.getId());
        //重新保存角色中间表
        List<UserRole> userRoles = new ArrayList<>();
        userDto.getRoleVoIds().forEach(r -> {
            userRoles.add(UserRole.builder()
                    .userId(user.getId())
                    .roleId(Long.valueOf(r))
                    .dataState(SuperConstant.DATA_STATE_0)
                    .build());
        });
        userRoleMapper.batchInsert(userRoles);
    }

    /**
     * 重置密码
     *
     * @param userId
     */
    @Override
    public void resetPasswords(Long userId) {
        String password = BCrypt.hashpw(securityProperties.getDefaultPassword(), BCrypt.gensalt());
        User user = User.builder()
                .password(password)
                .id(userId)
                .build();
        userMapper.updateByPrimaryKeySelective(user);
    }
}
